package org.nokatag.system;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.noka.http.header.HeaderItem;
import org.noka.http.header.HeaderPrivateItem;
import org.nokatag.jdom.Document;
import org.nokatag.jdom.Element;
import org.nokatag.jdom.input.SAXBuilder;
import org.nokatag.timer.NTimer;
import org.nokatag.timer.NTimerItem;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import org.xml.sax.EntityResolver;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
/**
 * 读取系统配置信息
 * @author rebin
 *
 */
public class ConfigRead {

	public static void ConfigInit(String filePath){
		try{
			File file = new File(filePath);
			FileInputStream fileinputstream = new FileInputStream(file);
			ConfigInit(fileinputstream);
		}catch(Exception xe){

		}
	}

	@SuppressWarnings("unchecked")
	public static void ConfigInit(InputStream fileinputstream){
		SAXBuilder sb = new SAXBuilder(); // 新建立构造器
		try{
			sb.setEntityResolver(new EntityResolver() {
				public InputSource resolveEntity(String publicId,String systemId) throws SAXException, IOException {
					String DtdFile = systemId.substring(systemId.lastIndexOf("/")+1, systemId.length());
					URL sb =Thread.currentThread().getContextClassLoader().getResource(DtdFile);
					System.out.println("noka dtd file path is:"+sb.toString());
					InputSource source = new InputSource(sb.openStream());
					source.setPublicId(publicId);
					source.setSystemId(systemId);
					return source;
				}
			});
			Document doc = sb.build(fileinputstream);
			Element rootelement=doc.getRootElement();
			//-----------------系统信息-------------------------------------------------------------------------
			List<Element>  sysconfig = rootelement.getChildren("sysconfig");
			List<Element> options = sysconfig.get(0).getChildren("option");
			for(Element el:options){
				String key = el.getAttributeValue("key");
				String value=el.getAttributeValue("value");
				if(null==key || null==value)
					continue;
				if("default-language".equalsIgnoreCase(key))
					Concest.DEFAULTLANGUAGE=value;
				else if("is-dbug".equalsIgnoreCase(key))
					Concest.ISDBUG="true".equalsIgnoreCase(value);
				else if("sql-checkvalue".equalsIgnoreCase(key))
					Concest.SQLCHECKVALUE=value;
				else if("pass-key".equalsIgnoreCase(key))
					Concest.SQLKEY=value;
				else if("db-connection-class".equalsIgnoreCase(key))
					Concest.CONNECTION=value;
				else if("dbutil-auto-close-session".equalsIgnoreCase(key))
					Concest.IS_AUTO_CLOSE_HIBERNATE_ESSION=("true".equalsIgnoreCase(value));
				else if("encoding".equalsIgnoreCase(key))//编码
					Concest.ENCODING=value;
				else if("proxool-alias".equalsIgnoreCase(key))//proxool连接池名称
					Concest.PROXOOL_ALIAS=value;
				else if("db-driver".equalsIgnoreCase(key))//jdbc连接驱动名称
					Concest.DB_DRIVER=value;
				else if("db-url".equalsIgnoreCase(key))//jdbc连接url
					Concest.DB_URL=value;
				else if("db-user".equalsIgnoreCase(key))//jdbc连接用户
					Concest.DB_USER=value;
				else if("db-password".equalsIgnoreCase(key))//jdbc连接密码
					Concest.DB_PASSWORD=value;
				else if("user-filter".equalsIgnoreCase(key)){//用户拦截器
					String url_pattern = el.getTextTrim();//路径
					Concest.USER_FILTER.add(new NFilter(value,url_pattern));
				}else if("dbgrid-dataserver".equalsIgnoreCase(key))//用户自定义数据处理引擎
					Concest.DBGRID_DATA_SERVER_CLASS=value;
				else if("spring-sessionFactory".equalsIgnoreCase(key))//spring sessionFactory
					Concest.DB_SPRING_SESSION_FACTORY=value;
				else if("button-filter".equalsIgnoreCase(key))//自定义button拦截类
					Concest.BUTTON_FILTER_CLASS=value;
				else if("rootpath-rule".equalsIgnoreCase(key))//rootpath生成规则
					Concest.ROOT_PATH_RULE=value;
				else if("cookie-domain".equalsIgnoreCase(key))//cookie域名
					Concest.COOKIE_DOMAIN=value;
				else if("dbgrid-style".equalsIgnoreCase(key))//cookie域名
					Concest.DBGRID_STYLE=value;
				else if("public-style".equalsIgnoreCase(key))//cookie域名
					Concest.PUBLIC_STYLE=value;
				else if("default-datetime".equalsIgnoreCase(key))//默认日期时间格式
					Concest.DEFAULT_DATETIME=value;
				else if("default-date".equalsIgnoreCase(key))//默认日期格式
					Concest.DEFAULT_DATE=value;
				else if("default-time".equalsIgnoreCase(key))//默认时间格式
					Concest.DEFAULT_TIME=value;
				else if("dbgrid-settable".equalsIgnoreCase(key))//dbgrid保存的表名
					Concest.DBGRID_SET_TABLE=value.replaceAll("(?i)\\$\\{rootdir\\}",Concest.ROOTDIR);
			}
			//--------------------------------------------------------------------------------------------------
			if(sysconfig.get(0).getChildren("spring")!=null && !sysconfig.get(0).getChildren("spring").isEmpty()){
				Element spring = (Element)sysconfig.get(0).getChildren("spring").get(0);
				String prefix = spring.getAttributeValue("prefix");
				if(null!=prefix){
					Concest.SPRING_STARTS_WITH = prefix;
				}
				String autowire = spring.getAttributeValue("autowire");
				if("AUTOWIRE_AUTODETECT".equals(autowire)){
					Concest.SPRING_AUTOWIRE_MODE = AutowireCapableBeanFactory.AUTOWIRE_AUTODETECT;
				}else if("AUTOWIRE_BY_NAME".equals(autowire)){
					Concest.SPRING_AUTOWIRE_MODE = AutowireCapableBeanFactory.AUTOWIRE_BY_NAME;
				}else if("AUTOWIRE_BY_TYPE".equals(autowire)){
					Concest.SPRING_AUTOWIRE_MODE = AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE;
				}else if("AUTOWIRE_CONSTRUCTOR".equals(autowire)){
					Concest.SPRING_AUTOWIRE_MODE = AutowireCapableBeanFactory.AUTOWIRE_CONSTRUCTOR;
				}else if("AUTOWIRE_NO".equals(autowire)){
					Concest.SPRING_AUTOWIRE_MODE = AutowireCapableBeanFactory.AUTOWIRE_NO;
				}else{
					Concest.SPRING_AUTOWIRE_MODE = AutowireCapableBeanFactory.AUTOWIRE_AUTODETECT;
				}
			}
			//--------------------------------------------------------------------------------------------------
			if(sysconfig.get(0).getChildren("file-save")!=null && !sysconfig.get(0).getChildren("file-save").isEmpty()){
				Element fileSave = (Element)sysconfig.get(0).getChildren("file-save").get(0);
				String table = fileSave.getAttributeValue("table");
				String dir = fileSave.getAttributeValue("position");
				String utilclass=fileSave.getAttributeValue("utilclass");
				if(null!=dir){
					Concest.FILESERVERPATH=dir.replaceAll("(?i)\\$\\{rootdir\\}",Concest.ROOTDIR);
					//----------------创建文件初始目录-----------------------------------------------------------
					try{
						File ufile = new File(Concest.FILESERVERPATH);
						if(ufile.exists()){
							ufile.mkdirs();
						}
					}catch(Exception se){
					}
					//--------------------------------------------------------------------------------------------
				}
				if(null!=table){
					Concest.FILEDBSAVE_TABLE=table;//数据库
				}
				if(null!=utilclass){//默热认文件处理类
					Concest.UP_FILE_INPUT_URIL = utilclass;
				}
			}
			//-----------------替换列表--------------------------------------------------------------------------
			List<Element> revaluelist = sysconfig.get(0).getChildren("rewritlist");
			for(Element e:revaluelist){
				String key = e.getAttributeValue("key");
				String revalue = e.getAttributeValue("revalue");
				String type = e.getAttributeValue("type");
				Concest.REVALUELIST.add(new ReValueDoc(key,revalue,type));
			}
			//-----------------浏览器缓存-----------------------------------------------------------------------------
			List<Element>  cache_files = rootelement.getChildren("cache-files");
			if(cache_files!=null && !cache_files.isEmpty()){
				Concest.CACHE_FILE="true".equalsIgnoreCase(cache_files.get(0).getAttributeValue("cache"));
				Concest.EXTERNAL_CACHE_FILE_PREFIX=cache_files.get(0).getAttributeValue("prefix");
				Concest.EXTERNAL_CACHE_FILE_SKIP=","+cache_files.get(0).getAttributeValue("skip")+",";
				Concest.EXTERNAL_CACHE_FILE_JSZIP = "true".equals(cache_files.get(0).getAttributeValue("jszip"));//是否压缩
				Concest.EXTERNAL_CACHE_FILE_CSZIP = "true".equals(cache_files.get(0).getAttributeValue("cszip"));//是否压缩
				List<Element>  cache_file=cache_files.get(0).getChildren("cache-file");
				if(cache_file!=null && !cache_file.isEmpty()){
					for(Element c:cache_file){
						String extension = c.getAttributeValue("extension");//扩展名 *.js
						String expires = c.getAttributeValue("expires");//到期期限 2D 表示2天,2h表示2小时,2m表示2分 2s表示2秒
						Concest.CACHE_FILES.put(extension,expires);
					}
				}
			}
			//===============协议头列表============================================================================
			List<Element>  http_headers = rootelement.getChildren("http-headers");
			if(null!=http_headers && !http_headers.isEmpty()){
				//---------------公共协议头------------------------------------------------------------------------
				List<Element> header_public =  http_headers.get(0).getChildren("headers-public");
				if(null!=header_public && !header_public.isEmpty()){
					List<Element>  headers = header_public.get(0).getChildren("header");
					if(null!=headers && !headers.isEmpty()){
						for(Element c:headers){
							Concest.HTTP_HEADER_PUBLICS.add(new HeaderItem(c.getAttributeValue("key"), c.getText()));
						}
					}
				}
				//---------------私有协议头------------------------------------------------------------------------
				List<Element> header_private =  http_headers.get(0).getChildren("headers-pravate");
				if(null!=header_private && !header_private.isEmpty()){
					for(Element header:header_private){
						List<Element> headers = header.getChildren("header");
						String dir = header.getAttributeValue("dir");//私有目录
						Boolean forpublic = "true".equals(header.getAttributeValue("forpublic"));//是否继承公共协议头，true|false
						HeaderPrivateItem hp = new HeaderPrivateItem(dir,forpublic);
						if(null!=headers && !headers.isEmpty()){
							for(Element c:headers){
								hp.addHeader(new HeaderItem(c.getAttributeValue("key"), c.getText()));
							}
							Concest.HTTP_HEADER_PRIVATES.add(hp);
						}
					}
				}
			}
			//---------------数据表格------------------------------------------------------------------------------
			List<Element>  bgrids = rootelement.getChildren("dbgrid");
			if(bgrids!=null && !bgrids.isEmpty()){
				for(Element c:bgrids){
					String id = c.getAttributeValue("id");
					String value =c.getText();
					for (Map.Entry<String, String> m : Concest.PAGETEMP.entrySet()) {
						value=value.replace("${"+m.getKey()+"}", m.getValue());
					}
					Concest.TABLEMODESTR.put("dbgrid_"+id,value);
				}
			}
			//---------------折叠菜单------------------------------------------------------------------------------
			List<Element>  accords = rootelement.getChildren("accord");
			if(accords!=null && !accords.isEmpty()){
				for(Element c:accords){
					String id = c.getAttributeValue("id");
					String value =c.getText();
					Concest.TABLEMODESTR.put("accord_"+id, value);
				}
			}
			//---------------数据子表------------------------------------------------------------------------------
			List<Element>  subgrids = rootelement.getChildren("subgrid");
			if(subgrids!=null && !subgrids.isEmpty()){
				for(Element c:subgrids){
					String id = c.getAttributeValue("id");
					String value =c.getText();
					Concest.TABLEMODESUBSTR.put(Integer.parseInt(id), value);
				}
			}
			//---------------数据表自定义格子显示-----------------------------------------------------------------
			List<Element>  cellbodys = rootelement.getChildren("cellbody");
			if(cellbodys!=null && !cellbodys.isEmpty()){
				for(Element c:cellbodys){
					String id = c.getAttributeValue("id");
					String value =c.getText();
					Concest.TABLEMODECELLBODY.put(Integer.parseInt(id), value);
				}
			}
			//---------------kword-------------------------------------------------------------------------------
			List<Element>  kwords = rootelement.getChildren("kword");
			if(kwords!=null && !kwords.isEmpty()){
				for(Element c:kwords){
					String id = c.getAttributeValue("id");
					String value =c.getAttributeValue("value");
					Concest.KWORD_CONFIG.put("kword_"+id, value);
				}
			}
			//--------------timer-------------------------------------------------------------------------------
			SimpleDateFormat de=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); //格式化时间
			List<Element>  timers = rootelement.getChildren("timers");
			if(timers!=null && !timers.isEmpty()){
				List<Element>  timer=timers.get(0).getChildren("timer");
				if(timer!=null && !timer.isEmpty()){
					for(Element c:timer){
						String TimerID = c.getAttributeValue("TimerID");
						String DoType = c.getAttributeValue("DoType");
						String TimerPrave = c.getAttributeValue("TimerPrave");
						String ClassUrl = c.getAttributeValue("ClassUrl");
						String Delayed = c.getAttributeValue("Delayed");
						String start = c.getAttributeValue("start");
						List<Object> ClassPrave = null;//参数
						NTimerItem nt = null;
						//------------定时器参数--------------------------------
						List<Element>  parsList = c.getChildren("prave");
						if(parsList.size()>0){
							ClassPrave = new ArrayList<Object>();
							for(Element par:parsList){
								ClassPrave.add(par.getText());
							}
						}
						//-----------------------------------------------------
						Delayed=(null==Delayed?"3":Delayed);
						if("TIMER_INTERVAL_SECOND".equals(DoType)){
							nt = new NTimerItem(TimerID,NTimer.TIMER_INTERVAL_SECOND,TimerPrave,ClassUrl,Delayed,(start==null?null:de.parse(start)),ClassPrave);
						}else if("TIMER_INTERVAL_MINUTE".equals(DoType)){
							nt = new NTimerItem(TimerID,NTimer.TIMER_INTERVAL_MINUTE,TimerPrave,ClassUrl,Delayed,(start==null?null:de.parse(start)),ClassPrave);
						}else if("TIMER_INTERVAL_HOUR".equals(DoType)){
							nt = new NTimerItem(TimerID,NTimer.TIMER_INTERVAL_HOUR,TimerPrave,ClassUrl,Delayed,(start==null?null:de.parse(start)),ClassPrave);
						}else if("TIMER_INTERVAL_DAY".equals(DoType)){
							nt = new NTimerItem(TimerID,NTimer.TIMER_INTERVAL_DAY,TimerPrave,ClassUrl,Delayed,(start==null?null:de.parse(start)),ClassPrave);
						}else if("TIMER_INTERVAL_WEEK".equals(DoType)){
							nt = new NTimerItem(TimerID,NTimer.TIMER_INTERVAL_WEEK,TimerPrave,ClassUrl,Delayed,(start==null?null:de.parse(start)),ClassPrave);
						}else if("TIMER_DAY_OF_TIME".equals(DoType)){
							nt = new NTimerItem(TimerID,NTimer.TIMER_DAY_OF_TIME,TimerPrave,ClassUrl,Delayed,(start==null?null:de.parse(start)),ClassPrave);
						}else if("TIMER_WEEK_OF_TIME".equals(DoType)){
							nt = new NTimerItem(TimerID,NTimer.TIMER_WEEK_OF_TIME,TimerPrave,ClassUrl,Delayed,(start==null?null:de.parse(start)),ClassPrave);
						}else if("TIMER_MONTH_OF_TIME".equals(DoType)){
							nt = new NTimerItem(TimerID,NTimer.TIMER_MONTH_OF_TIME,TimerPrave,ClassUrl,Delayed,(start==null?null:de.parse(start)),ClassPrave);
						}else if("TIMER_YEAR_OF_TIME".equals(DoType)){
							nt = new NTimerItem(TimerID,NTimer.TIMER_YEAR_OF_TIME,TimerPrave,ClassUrl,Delayed,(start==null?null:de.parse(start)),ClassPrave);
						}else if("TIMER_MONTH_MAXDAY_OF_TIME".equals(DoType)){
							nt = new NTimerItem(TimerID,NTimer.TIMER_MONTH_MAXDAY_OF_TIME,TimerPrave,ClassUrl,Delayed,(start==null?null:de.parse(start)),ClassPrave);
						}
						if(null!=nt){
							Concest.TIMER_ITEMS.add(nt);
						}
					}
				}
			}
		}catch(Exception se){
			se.printStackTrace();
			BugInfoWrint.Print(se);
		}
	}
}